This chapter deals entirely with system polling and events. It details how Tools Plus reports events, and how your application should respond to them. This chapter is laid out as follows:
• System polling is detailed
• Task switching is detailed
• The Macintosh’s event reporting and queuing mechanism is explained
• Automatic event filtering when a watch cursor is displayed is
explained
• Tools Plus’s event record and its fields are detailed
• Event modifier keys are explained (Caps Lock, Shift, Option,
Command and Control)
• The PollSystem function is detailed. All possible event codes are
listed here. PollSystem’s internal workings are also described.
• Each possible event is detailed, along with the correct response
that should be taken by your application
• A Field To Event Cross Reference table quickly identifies when each
field in the polling record is used
• The polling routine’s execution time is discussed for applications
in which speed is critical
What Is Polling?
````````````````
In the purest sense, polling is a periodic process in which your application asks what has happened? This gives your application the ability to respond to its environment, as well as to its own internal mechanisms. The Macintosh’s Toolbox Event Manager creates and manages those events, however, they are at a very low level and require a lot of work before your application can use them (they are simplified by Tools Plus).
Your application must constantly poll the system and respond to the reported events, and it does so with Tools Plus’s polling routine, PollSystem.
PollSystem is the heart-beat of Tools Plus. It is called by your application to obtain events generated by the user, such as typing or clicking the mouse. In fact, all events are obtained this way. The big difference here is that PollSystem does everything it possibly can before handing an event back to your application. Some events are processed internally and are never reported to your application, such as when the user types in an Editing Field (the field automatically processes the typing). Other events are reported to your application, such as when the user clicks a button. The events reported to your application are in a format that your application can readily use.
Task Switching
``````````````
With the introduction of System 5, MultiFinder made cooperative multi-tasking a reality on the Macintosh. Cooperative, or “switched” multi-tasking as it is often called, lets several applications run simultaneously by cycling amongst all the tasks. The term “cooperative” is used because each application must cooperate with all others by relinquishing control to give the others some processing time.
Only one application can be active (the front most window) at a time under MultiFinder and System 7, even though, potentially, you may be able to see dozens of windows from multiple applications simultaneously. Therefore, the active application is temporarily “suspended” when another application (or desk accessory) is activated. Please note that suspended applications can also receive events and processing time.
There are two kinds of “switches” that occur in cooperative multi-tasking: minor and major. In a major switch, your application is either suspended when another application or desk accessory is activated, or resumed when your application is activated. The doSuspend and doResume events report this occurrence to your application. In a minor switch, your application is given some processing time, then it releases control to another application or desk accessory.
PollSystem takes care of task switching. When your application calls PollSystem, a major or minor switch always occurs. You only need to concern yourself with minor switches by calling PollSystem as frequently as possible. In other words, don’t let your application run for ten seconds before calling PollSystem, or other applications will work jerkily, or worse yet, appear to mysteriously “hang” when in actuality they just aren’t getting enough cooperation from your application. The doSuspend and doResume events detail how your application should respond to a major switch.
See the SIZE resource to specify how your application will behave while suspended, and during the transition from being active to inactive or vice versa.
Background Processing
`````````````````````
Applications written with Tools Plus can easily be made to do “background processing,” that is, performing an on-going process while waiting for events. An example of this is repaginating a word-processing document, or searching a large file for specific records.
When PollSystem returns with a value of false, it indicates that no event has occurred. This is commonly called a “null event.” Usually, your application won’t do anything other than idle in the main event loop. If your application does background processing, it should do its work only when it receives a doNothing event. A single cycle of your application’s background process should take no longer than 1/60 of a second. Otherwise, other applications may run sluggishly or in spurts and jumps.
You can set the rate at which your application receives doNothing events by using the SetNullTime routine. The WaitAvail routine can be used to determine if the Macintosh your application is running on supports scheduled doNothing events.
Macintosh Events
````````````````
The Toolbox Event Manager, as described in chapter 8 of Inside Macintosh Volume I, is the link between your application and its user, and its machine environment. Whenever the user types a key on the keyboard or numeric keypad, presses the mouse button, or inserts a disk in the disk drive, the Macintosh makes your application aware of this by means of an event.
In addition to monitoring the user’s actions, the Macintosh’s Toolbox Event Manager also detects other types of events that serve to inform your application as to “what is happening.” Such an event is reported when a partially obscured window is uncovered and its contents need to be redrawn (update event).
The Toolbox Event Manager’s events contain an event code that identifies the type of event. Event codes are available as constants. Later, you will learn how the Macintosh’s Toolbox Event Manager’s events are automatically translated into Tools Plus events. The list below is for reference purposes only, since your application will likely never make use of the Toolbox Event Manager’s events directly.
CONST
nullEvent =0; {no event detected }
mouseDown =1; {mouse button was pressed down }
mouseUp =2; {mouse button was released }
keyDown =3; {a key was pressed }
keyUp =4; {a key was released }
autoKey =5; {a key was held down and is repeating }
updateEvt =6; {a window must be updated (refreshed) }
diskEvt =7; {a disk was inserted }
activateEvt =8; {a window was activated or deactivated }
networkEvt =10; {network }
driverEvt =11; {device driver }
app1Evt =12; {application-defined event number 1 }
app2Evt =13; {application-defined event number 2 }
app3Evt =14; {application-defined event number 3 }
The watch cursor is used to indicate a long wait, such as when a lengthy process is being conducted or when printing is being done. Your application can display the watch cursor by calling CursorShape(watchCursor).
While the watch cursor is displayed, your application may choose not to call PollSystem, since it doesn’t care what the user is doing and will want to ignore mouse clicks and typing anyway. Unfortunately, this does not give the user the opportunity to halt a lengthy process, nor does it give other applications running under MultiFinder or System 7 any processing time. Tools Plus solves this dilemma by shifting into a busy mode when the watch cursor is displayed.
When your application displays the watch cursor, subsequent calls to PollSystem will filter out (discard) the effects of, and the events that may be generated by the user clicking the mouse or typing. The exception to this, of course, is when the user types Command-. which tells your application to halt the process. This lets your application call PollSystem regularly while it is busy conducting a lengthy task, knowing that any key or mouse event is meaningful (it indicates that the user wants to halt the process). Your application may choose not to call PollSystem or to ignore the Command-. key if it’s busy only for a very short time.
When your application is finished its lengthy process, it can either change the cursor itself or call ResetCursor to change the cursor to its appropriate shape according to its position on the screen.
Note: When the watch cursor is displayed, your application may receive
Tools Plus events that are unrelated to mouse clicks or typing,
such as redrawing a window (doRefresh) or a disk insert event.
Warning: If your application is running under MultiFinder or System 7,
it is possible to switch to another application while a watch
cursor is displayed unless your active window is of type
dBoxProc.
The Event Queue
```````````````
When events are generated, they are stored in an event queue. When your application is ready to process them, the oldest event is removed from the queue and processed first. This journaling mechanism lets the Macintosh remember a series of rapidly occurring events and store them until your application is ready to process them.
Events have a certain priority, meaning that some events will be processed before others, regardless of when they were actually generated. Their priority is as such:
1. activate/deactivate a window
2. mouse-down/up, key down/up, disk insert, network driver,
application-defined events (first in first out)
3. auto-key (key pressed and held, causing it to repeat)
4. update a window (refresh a window in front-to-back order)
The priority of events insures that illogical events are not reported. For instance, the user may click twice in a window’s close box before an application gets around to processing the event. The first click will signal your application to close the window. The second click will not be reported as a click in a non-existent (closed) window. The second click’s location will be analyzed after the window is closed, and reported accordingly.
Tools Plus works in an identical manner when interacting with the event queue. In fact, Tools Plus obtains events from the Macintosh’s Toolbox Event Manager and translates them into something useful before reporting them to your application.
Note: The event queue can store a maximum of 20 events. If your
application is so busy that it lets more than 20 events accumulate
in the queue, the oldest events is discarded to make room for
the new ones.
Tools Plus Event Record
```````````````````````
Whenever Tools Plus detects an event that cannot be processed automatically, it provides your application with the event’s information in the form of an event record. Although the event record looks cumbersome, it is logically organized and is very easy to use.
The entire record accounts for every type of event that can possibly occur. During any one specific event, your application will only need to access one or two of these fields. Later in this chapter when you are told how to respond to the various Tools Plus events, you will also be told which fields in the event record hold pertinent information.
The event record is defined as follows (C first, then Pascal):
/*= Polling record's "event modifiers" info*/
union TPModifiersRec { /*This variable record contains */
/* an event's "modifiers" in 2 */
/* formats… */
/* • Macintosh Event: */
short Num; /* integer (bit operations */
/* required) */
/* • Modifier integer parsed */
struct { /* into components: */
unsigned short bit15 :1; /* (reserved bit) */
unsigned short bit14 :1; /* (reserved bit) */
unsigned short bit13 :1; /* (reserved bit) */
unsigned short ControlKey :1; /* Control key was down at event */
unsigned short OptionKey :1; /* Option key was down at event */
unsigned short CapsLock :1; /* Caps Lock was down at event */
unsigned short ShiftKey :1; /* Shift key was down at event */
unsigned short CmdKey :1; /* Command key was down at event */
unsigned short MouseUp :1; /* Mouse button was UP at event */
unsigned short bit6 :1; /* (reserved bit) */
unsigned short bit5 :1; /* (reserved bit) */
unsigned short bit4 :1; /* (reserved bit) */
unsigned short bit3 :1; /* (reserved bit) */
unsigned short bit2 :1; /* (reserved bit) */
unsigned short bit1 :1; /* (reserved bit) */
unsigned short bit0 :1; /* (reserved bit) */
} Bits; /* */
};
typedef union TPModifiersRec TPModifiersRec;
/*= Polling record's "button" info*/
struct TPPollButtonRec {
short Num; /*Button number */
Boolean DoubleClick; /*Did a double-click occur in the*/
Menu: TPPollMenuRec; {Menu number/menu item of an }
{ event. }
Key: TPPollKeyRec; {Key number & character of key- }
{ stroke. }
Mouse: TPPollMouseRec; {Click/drag info: [1..3] where &}
{ when. }
Modifiers: TPModifiersRec; {Modifier flags }
Event: EventRecord {Pascal event record }
end;
TPPollPointer = ^TPPollRecord; {Pointer to a Polling record, in}
{ case you want to reduce }
{ global variable memory. }
Event Record Fields
```````````````````
The event record’s structure is best explained by detailing each subrecord and field with a programmer’s approach. This explanation looks at the event record in detail, starting from the record level and ending with fields.
Your application should define a variable or pointer than lets it use the polling record. In the following text, the assumption has been made that the variable is called Poll. If your application uses a pointer, replace Poll with Poll^ in the text.
Note that all fields are not valid at the same time. For example, the window field would not contain a valid number when a menu event was reported, because menus work independently of windows. A “Field to Event Cross Reference” is included later in this section, and it lists each field and the events that make use of it.
Poll
````
This variable is the entire polling record, and is of TPPollRecord type (it is a TPPollPointer type if your application is using a pointer to the record)
Poll.What
`````````
Event Code: Explains what type of event has occurred. This field is used by your application to decide what action should be taken, and what other fields contain pertinent event information.
Poll.Window
```````````
Window Number: Window number on which the event occurred.
Poll.Button
```````````
Button Record
Poll.Button.Num
```````````````
Button Number: Button number that was clicked by the user.
Poll.Button.DoubleClick
```````````````````````
Button’s Double-Click Status: Was the button double-clicked?
Poll.ScrollBar
``````````````
Scroll Bar Record
Poll.ScrollBar.Num
``````````````````
Scroll Bar Number: Scroll bar number that was clicked by the user. This does not include a scroll bar that is part of a list box.
Poll.ScrollBar.Part
```````````````````
Scroll Bar Part: Part of scroll bar that was clicked by user (up arrow, down arrow, “page up” region, “page down” region, thumb)
Poll.Field
``````````
Editing Field Number: Editing field that was clicked by the user.
Poll.ListBox
````````````
List Box Record
Poll.ListBox.Num
````````````````
List Box Number: List box number that was clicked by the user.
Poll.ListBox.DoubleClick
````````````````````````
List Box’s Double-Click Status: Was a line in the list box double-clicked?
Poll.Menu
`````````
Menu Record
Poll.Menu.Num
`````````````
Menu Number: Menu number that was selected by the user. This could be a pull-down menu, a hierarchical menu, or a pop-up menu.
Poll.Menu.Item
``````````````
Menu Item: Item number that was selected by the user.
Poll.Key
````````
Key Record
Poll.Key.Code
`````````````
Key Number: Number of the key that was pressed, released, or is auto-repeating. This key code is a key number that is not affected by the Caps Lock, Shift, Option, Command and Control modifiers.
Poll.Key.Chr
````````````
Key Character: Character resulting from a key that was pressed, released, or is auto-repeating. This character is altered by the Caps Lock, Shift, Option, Command and Control modifiers.
Poll.Mouse
``````````
Mouse Activity Record
Poll.Mouse.What
```````````````
Mouse Event Code: Type of mouse event has occurred (i.e. single, double, triple-click, dragging, etc.). This field is used by your application to decide what action should be taken, and which other fields in the mouse record contain pertinent information.
Poll.Mouse.Down
```````````````
Mouse-Down Array Record: The elements of the array contain the first, second and third mouse-down events of a single, double, or triple-click, or drag.
Poll.Mouse.Down[1].Where
````````````````````````
Mouse Down Location: Location of 1st mouse-down in a single, double, or triple-click, or drag. Window’s local co-ordinates are used.
Poll.Mouse.Down[1].When
```````````````````````
Mouse Down Time: Time of 1st mouse-down. Number of “ticks” since startup.
Poll.Mouse.Down[1].Modifiers
````````````````````````````
Mouse Down Modifier Record: Event modifiers at the time of the 1st mouse-down event. See the note on modifiers below.
Poll.Mouse.Down[2]…
```````````````````
Mouse-Down Array Record: Same fields, but for 2nd mouse-down in a double, or triple-click, or drag.
Poll.Mouse.Down[3]…
```````````````````
Mouse-Down Array Record: Same fields, but for 3rd mouse-down in a triple-click, or drag.
Poll.Mouse.Up
`````````````
Mouse-Up Array Record: The elements of the array contain the first, second and third mouse-up events of a single, double, or triple-click, or drag.
Poll.Mouse.Up[1].Where
``````````````````````
Mouse Up Location: Location of 1st mouse-up in a single, double, or triple-click, or drag. Window’s local co-ordinates are used.
Poll.Mouse.Up[1].When
`````````````````````
Mouse Up Time: Time of 1st mouse-up. Number of “ticks” since startup.
Poll.Mouse.Up[1].Modifiers
``````````````````````````
Mouse Up Modifier Record: Event modifiers at the time of the 1st mouse-up event. See the note on modifiers below.
Poll.Mouse.Up[2]…
`````````````````
Mouse-Up Array Record: Same fields, but for 2nd mouse-up in a double, or triple-click, or drag.
Poll.Mouse.Up[3]…
`````````````````
Mouse-Up Array Record: Same fields, but for 3rd mouse-up in a triple-click, or drag.
Poll.Mouse.Where
````````````````
Mouse Location: Current mouse location in window’s local co-ordinates.
Poll.Modifiers
``````````````
Modifier Record: Event modifiers at the time when the event occurred. See the note on modifiers below.
Poll.Event
``````````
The Event Manager’s Event Record: A completely unaltered event record as retrieved from the Toolbox Event Manager. This is used for applications that want to process their own custom events or custom controls.
Note: For C programmers… The polling record’s arrays are documented as
using Pascal nomenclature (the elements are numbered 1, 2 and 3).
In C, the same array’s elements are numbered 0, 1 and 2 (they
start at zero). In this manual when C programmers read:
Poll.Mouse.Down[1].Where
it indicates the first element of the array, which translates to